<?php

use think\Collection;
use think\facade\Config;
use think\facade\Cache;
use think\facade\Response;
use think\facade\Env;
use think\Model;
use aes\CryptAES;

/**
 * 封装返回值
 * @param $data
 * @param $errorCode
 * @param string $errorMessage
 * @return array
 */
function send_response($data, $errorCode, $errorMessage = '') {
    $response['errorCode'] = $errorCode;
    $response['message'] = $errorMessage ? $errorMessage : Config::pull('errorcode')[$errorCode];

    if ($data instanceof Collection || $data instanceof Model) {
        $data = $data->toArray();
    }
    if (is_array($data)) {
        $response['data'] = $data;
    }

    return $response;
}

/**
 * @desc 正确返回
 * @param $data
 * @param $errorCode
 * @param string $errorMessage
 * @return mixed
 */
function json_success($data, $errorCode, $errorMessage = '') {
    $response['errorCode'] = $errorCode;
    $response['message'] = $errorMessage ? $errorMessage : Config::pull('errorcode')[$errorCode];

    if ($data instanceof Collection || $data instanceof Model) {
        $data = $data->toArray();
    }
    $response['data'] = $data;
    return $response;
}

/**
 * @desc 错误返回
 * @param $errorCode
 * @param string $errorMessage
 * @return mixed
 */
function json_error($errorCode, $errorMessage = '') {
    $response['errorCode'] = $errorCode;
    $response['message'] = $errorMessage ? $errorMessage : Config::pull('errorcode')[$errorCode];
    return $response;
}

/**
 * 检查是否为内网ip
 * @param $ip
 * @return int
 */
function check_intranet($ip) {
    $addrArr = array(
        '10.0.0.0|10.255.255.255',
        '172.16.0.0|172.31.255.255',
        '192.168.0.0|192.168.255.255',
        '169.254.0.0|169.254.255.255',
        '127.0.0.0|127.255.255.255'
    );
    $longIp = ip2long($ip);
    if ($longIp != -1) {
        foreach ($addrArr AS $addr) {
            list($start, $end) = explode('|', $addr);
            if ($longIp >= ip2long($start) && $longIp <= ip2long($end))
                return true;
        }
    }
    return false;
}

/**
 * 生成指定长度的随机字符串
 * @param int $len 长度
 * @param string $type
 * @return string
 */
function random_string($len = 8, $type = 'str') {
    switch ($type) {
        case 'str': {
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            break;
        }
        case 'int': {
            $chars = '0123456789';
            break;
        }
        default: {
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
            break;
        }
    }
    $chars = str_shuffle($chars);
    return substr($chars, 0, $len);
}

/**
 * 重新指定数组的索引
 * @param array $arr 数组
 * @param string $key 键名
 * @return array
 */
function reindex_array($arr, $key) {
    if (!is_array($arr) || empty($arr)) {
        return array();
    }

    $row = array_shift($arr);
    if (!array_key_exists($key, $row)) {
        return array();
    }
    array_unshift($arr, $row);

    $res = array();
    foreach ($arr as $row) {
        $res[$row[$key]] = $row;
    }

    return $res;
}

/**
 * 提取数组某一个key的值
 * @param array $arr
 * @param string $extract_key
 * @return array
 */
function extract_array($arr, $extract_key) {
    $res = array();
    if (is_array($arr)) {
        foreach ($arr as $row) {
            $res[] = $row[$extract_key];
        }
    }

    return $res;
}

function get_cross_headers() {
    $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*";
    $headers = [
        "Access-Control-Allow-Origin" => $host_name,
        "Access-Control-Allow-Credentials" => 'true',
        "Access-Control-Allow-Headers" => "x-token,x-uid,x-token-check,x-requested-with,content-type,Host,Auth-Token,Authorization",
        "Access-Control-Expose-Headers" => 'Auth-Token'
    ];

    return $headers;
}

/**
 * @desc 生成订单号
 * @return string
 */
function generate_order_number() {
    $order = date('Ymd') . substr(time(), -5);
    $order .= substr(microtime(), 2, 5) . sprintf('%03d', mt_rand(0, 999));

    return $order;
}

/**
 * @desc 生成订单号
 * @return string
 */
function generate_order_no() {
    $uniqueID = substr(uniqid(), 7, 13);
    $order = date('YmdHis') . substr(implode(NULL, array_map('ord', str_split($uniqueID, 1))), 0, 12);
    return $order;
}

//密码生成方法
function encrypt_password($password, $salt) {
    $password = trim($password);

    return md5($password . $salt);
}

function array_ksort($list) {
    ksort($list);
    foreach ($list as $k => $v) {
        if (is_array($v)) {
            $list[$k] = array_ksort($v);
        }
    }

    return $list;
}

/**
 * 计算两个日期之间相差的天数
 */
function count_days($a, $b) {
    return round(abs(strtotime($a) - strtotime($b)) / 86400);
}

/**
 * 二维数组按照某字段排序
 * $array 待排序数组
 * $key 排序的键名
 * $sort 1 - 默认，按升序排列。2 - 按降序排列。(Z-A)
 * return 排序后的数组
 */
function array_sort_bykey($array = [], $key = '', $sort = 1) {
    $keyArray = array();
    foreach ($array as $v) {
        $keyArray[] = $v[$key];
    }

    $sort = ($sort == 1) ? SORT_ASC : SORT_DESC;
    array_multisort($keyArray, $sort, $array);

    return $array;
}

/**
 * 获取冷数据表-年月信息
 * @param $startDate
 * @param $endDate
 * @return array
 */
function get_cold_data_ym($startDate, $endDate) {

    $sTime = strtotime($startDate);
    $eTime = strtotime($endDate);

    $m = date("m", $sTime);
    $y = date("Y", $sTime);

    $sym = date("Ym", $sTime);
    $eym = date("Ym", $eTime);

    $ym = [];
    $i = 0;

    $_startDate = $startDate;
    $_endDate = date("Y-m-01 0:00:00", mktime(0, 0, 0, $m + 1, 1, $y));

    while ($sym <= $eym) {

        $tmp = [];
        $tmp['ym'] = $sym;
        $tmp['sdate'] = $_startDate;
        $tmp['edate'] = $_endDate;
        $ym[] = $tmp;

        $i++;
        $m1time = mktime(0, 0, 0, $m + $i, 1, $y);

        $sym = date("Ym", $m1time);
        $_startDate = date("Y-m-01 0:00:00", $m1time);
        $_endDate = ($sym == $eym) ? $endDate : date("Y-m-01 0:00:00", mktime(0, 0, 0, $m + $i + 1, 1, $y));
    }

    return $ym;
}

/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取（有可能被伪装）
 * @return mixed
 */
function get_client_ip($type = 0, $adv = true) {
    $type = $type ? 1 : 0;
    static $ip = null;
    if ($ip !== null)
        return $ip[$type];
    if ($adv) {
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos)
                unset($arr[$pos]);
            $ip = trim($arr[0]);
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip = $long ? array(
        $ip,
        $long
            ) : array(
        '0.0.0.0',
        0
    );

    return $ip[$type];
}

/**
 * 批量更新
 * @param string $tableName 表名（含前缀）
 * @param array $data 数据
 * @param string $field 主键字段
 * @return bool|int
 */
function batch_update($tableName = '', $data = array(), $field = '') {
    if (!$tableName || !$data || !$field) {
        return false;
    } else {
        $sql = 'UPDATE ' . $tableName;
    }
    $con = [];
    $conSql = [];
    $fields = [];
    foreach ($data as $key => $value) {
        $x = 0;
        foreach ($value as $k => $v) {
            if ($k != $field && !isset($con[$x]) && $x == 0) {
                $con[$x] = " set {$k} = (CASE {$field} ";
            } elseif ($k != $field && !isset($con[$x]) && $x > 0) {
                $con[$x] = " {$k} = (CASE {$field} ";
            }
            if ($k != $field) {
                $temp = $value[$field];

                if (is_operator($v) || is_numeric($v)) {
                    $conSql[$x] = !isset($conSql[$x]) ? " WHEN '{$temp}' THEN {$v} " : $conSql[$x] . " WHEN '{$temp}' THEN {$v} ";
                } else {
                    $conSql[$x] = !isset($conSql[$x]) ? " WHEN '{$temp}' THEN '{$v}' " : $conSql[$x] . " WHEN '{$temp}' THEN '{$v}' ";
                }

                $x++;
            }
        }
        $temp = $value[$field];
        if (!in_array($temp, $fields)) {
            $fields[] = $temp;
        }
    }
    $num = count($con) - 1;
    foreach ($con as $key => $value) {
        foreach ($conSql as $k => $v) {
            if ($k == $key && $key < $num) {
                $sql .= $value . $v . ' end),';
            } elseif ($k == $key && $key == $num) {
                $sql .= $value . $v . ' end)';
            }
        }
    }
    $str = implode(',', $fields);
    $sql .= " where {$field} in({$str})";

    $query = new \think\db\Query();
    $result = $query->execute($sql);

    return $result;
}

function is_operator($str) {

    $operator_array = array(
        "+",
        "-",
        "*",
        "/",
        "%"
    );

    foreach ($operator_array as $operator) {
        if (strpos($str, $operator) !== false) {
            return true;
        }
    }

    return false;
}

/**
 * 递归数组，去掉默认的字符和驼峰转换；eg: ul_user_id => userId
 * @param $data array 需要格式化的数据
 * @param $replaceString string 需要去掉的字符
 * @return mixed
 */
function output_format($data, $replaceString = '') {
    if ($data instanceof Collection || $data instanceof Model) {
        $data = $data->toArray();
    }
    if (!is_array($data) || empty($data)) {
        return [];
    }
    $formatData = [];
    foreach ($data as $key => $val) {
        //替换字符
        if ($replaceString) {
            $newKey = str_replace($replaceString . '_', '', $key);
        } else {
            $newKey = $key;
        }

        //转换驼峰
        $newKey = lcfirst(str_replace(' ', '', ucwords(str_replace(['_'], ' ', $newKey))));

        //递归val
        if (is_array($val)) {
            $formatData[$newKey] = output_format($val, $replaceString);
        } else {
            //接口不返回null
            if ($val === null) {
                $val = '';
            }
            $formatData[$newKey] = $val;
        }
    }
    return $formatData;
}

/**
 * 数组去除空值
 * @param $arr array 数组
 * @param $trim bool 是否删除两边空格
 * @return string|array
 */
function array_remove_empty($arr, $trim = true) {
    if (!is_array($arr))
        return false;
    foreach ($arr as $key => $value) {
        if (is_array($value)) {
            array_remove_empty($arr[$key]);
        } else {
            $value = ($trim == true) ? trim($value) : $value;
            if ($value === "") {
                unset($arr[$key]);
            } else {
                $arr[$key] = $value;
            }
        }
    }
    return $arr;
}

/**
 * 截取3位小数保留精度一致,不会进位
 * @param float $float
 * @param int $num
 * @return float
 */
function cut_floor($float, $num = 3) {
    switch ($num) {
        case 2: {
                $float = floor($float * 100) * 1.00 / 100.00;
                break;
            }
        case 3: {
                $float = floor($float * 1000) * 1.000 / 1000.000;
                break;
            }
        case 4: {
                $float = floor($float * 10000) * 1.0000 / 10000.0000;
                break;
            }
        default : {
                $float = floor($float * 100) * 1.00 / 100.00;
            }
    }
    return $float;
}

/**
 * 判断数组是否二维数组
 * @param $data
 * @return bool
 */
function is_multi_array($data) {
    if (count($data) == count($data, COUNT_RECURSIVE)) {
        return false;
    } else {
        return true;
    }
}

/**
 * 计算当前时间所在周期, 默认统计周期5分钟
 * @param int $cycle
 * @return mixed
 */
function getTimeRange($cycle = 5) {
    $hour = date('H');
    $minute = date('i');
    $end = floor(($hour * 60 + $minute) / $cycle);
    if ($end == 0) {
        $arr['startTime'] = '00:00:00';
        $arr['endTime'] = '00:05:00';
    } else {
        $arr['startTime'] = floor(($end - 1) * $cycle / 60) . ':' . ($end - 1) * $cycle % 60 . ':00';
        $arr['endTime'] = floor($end * $cycle / 60) . ':' . $end * $cycle % 60 . ':00';
    }
    return $arr;
}

/**
 * 计算据现在间隔时间
 * @param int $time
 * @return bool|string
 */
function time2zh($time) {
    $now_time = time();
    $zh = date('Y-m-d H:i:s', $time);
    $diff = $now_time - $time;
    if ($diff < 60) {
        $zh = $diff . '秒';
    } elseif ($diff < 3600) {
        $zh = floor($diff / 60) . '分';
    } elseif ($diff < 3600 * 24) {
        $zh = floor($diff / 3600) . '小时';
    } elseif ($diff < 3600 * 24 * 7) {
        $zh = floor($diff / 86400) . '天';
    }
    return $zh;
}

/**
 * 封装返回值
 * @param string $data
 * @throws HttpResponseException
 */
function response_exception($data = '') {
    $type = Config::get('app.default_ajax_return');
    $response = Response::create($data, $type);
    throw new think\exception\HttpResponseException($response);
}

/**
 * 获取指定日期段内每一天的日期
 * @param  Date  $startDate 开始日期
 * @param  Date  $endDate   结束日期
 * @return Array
 */
function getDateFromRange($startDate, $endDate) {

    $starTimestamp = strtotime($startDate);
    $endTimestamp = strtotime($endDate);

    // 计算日期段内有多少天
    $days = ($endTimestamp - $starTimestamp) / 86400 + 1;

    // 保存每天日期
    $date = array();
    for ($i = 0; $i < $days; $i++) {
        $date[] = date('Y-m-d', $starTimestamp + (86400 * $i));
    }
    return $date;
}

/**
 * 验证时间格式
 * @param $dateTime
 * @return bool|false|string
 */
function validateTime(&$dateTime) {
    if (!$dateTime) {
        $dateTime = date('Y-m-d H:00:00');
    } else {
        if (!strtotime($dateTime)) {
            return false;
        }
        $dateTime = date('Y-m-d H:00:00', strtotime($dateTime));
    }
    return true;
}

/**
 * 查询时间范围跨度默认小于等于30天
 * @param $startDate
 * @param $endDate
 * @return bool
 */
function limitTimeRange($startDate, $endDate) {
    $starTimestamp = strtotime($startDate);
    $endTimestamp = strtotime($endDate);

    //计算日期段内有多少天
    $days = ($endTimestamp - $starTimestamp) / 86400 + 1;

    //判断时间跨度是否超过指定，默认30天
    if ($days > 30) {
        return false;
    }
    return true;
}

/**
 * @desc 使用header下载文件
 * @param string file_path  文件路径
 * @return null
 */
function downloadFile($file_path) {
    //判断路径是否存在
    if (!file_exists($file_path)) {
        echo "文件不存在";
        return;
    }

    $fp = fopen($file_path, "rb");  // 文件以二进制形式打开
    $ua = $_SERVER["HTTP_USER_AGENT"];

    //取得文件信息
    $file_size = filesize($file_path);
    $file_name = basename($file_path);
    $encoded_file_name = urlencode($file_name);
    $encoded_file_name = str_replace("+", "%20", $encoded_file_name);

    header('Content-Type: application/octet-stream;charset=utf-8');
    header("Accept-Ranges:bytes");
    header("Accept-Length:" . $file_size);

    // 兼容多浏览器下载
    if (preg_match("/MSIE/", $ua)) {
        header('Content-Disposition: attachment; filename=' . $encoded_file_name);
    } else if (preg_match("/Firefox/", $ua)) {
        header('Content-Disposition: attachment; filename*=utf8\'\'' . $file_name);
    } else {
        header('Content-Disposition: attachment; filename=' . $file_name);
    }

    // 清除缓存很重要
    ob_clean();
    flush();
    // 清除缓存很重要

    $buffer = 1024;
    $buffer_count = 0;

    while (!feof($fp) && $file_size - $buffer_count > 0) {
        $data = fread($fp, $buffer);
        $buffer_count += $buffer;
        echo $data;
    }

    fclose($fp);

    exit(); // 一定要使用exit退出，否则会导致输出excel文件无法打开
}

/**
 * @desc 文件大小转换  eg：118050056 = 112.58MB
 * @param $byte
 * @return string
 */
function calculate_file_size($byte) {
    $KB = 1024;
    $MB = 1024 * $KB;
    $GB = 1024 * $MB;
    $TB = 1024 * $GB;

    if ($byte < $KB) {
        return $byte . "B";
    } elseif ($byte < $MB) {
        return round($byte / $KB, 2) . "KB";
    } elseif ($byte < $GB) {
        return round($byte / $MB, 2) . "MB";
    } elseif ($byte < $TB) {
        return round($byte / $GB, 2) . "GB";
    } else {
        return round($byte / $TB, 2) . "TB";
    }
}

/**
 * @desc 文件删除
 * @param $path
 */
function delete_dir($path) {
    //如果是目录则继续
    if (is_dir($path)) {
        //扫描一个文件夹内的所有文件夹和文件并返回数组
        $p = scandir($path);
        foreach ($p as $val) {
            //排除目录中的.和..
            if ($val != "." && $val != "..") {
                //如果是目录则递归子目录，继续操作
                if (is_dir($path . $val)) {
                    //子目录中操作删除文件夹和文件
                    delete_dir($path . $val . '/');
                    //目录清空后删除空文件夹
                    @rmdir($path . $val . '/');
                } else {
                    //如果是文件直接删除
                    unlink($path . $val);
                }
            }
        }
    }
}

/**
 * @desc url base64编码
 * @param $string
 * @return mixed|string
 */
function url_safe_b64encode($string) {
    $data = base64_encode($string);
    $data = str_replace(array('+', '/', '='), array('-', '_', ''), $data);
    return $data;
}

/**
 * @desc url base64编码
 * @param $string
 * @return mixed|string
 */
function url_safe_b64decode($string) {
    $data = str_replace(array('-', '_'), array('+', '/'), $string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

/**
 * @desc 通知token base64编码处理
 * @param $string
 * @return mixed|string
 */
function token_safe_b64encode($string) {
    return  str_replace(array('+', '/', '='), array('-', '_', ''), $string);
}

/**
 * @desc 通知token base64编码处理
 * @param $string
 * @return mixed|string
 */
function token_safe_b64decode($string) {
    $data = str_replace(array('-', '_'), array('+', '/'), $string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return $data;
}


/**
 * @desc 字符转hex编码
 * @param $string
 * @return mixed|string
 */
function string2hex($string) {
    $hex = '';
    for ($i = 0; $i < strlen($string); $i++) {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

/**
 * @desc hex编码转字符
 * @param $hex
 * @return mixed|string
 */
function hex2string($hex) {
    $string = '';
    for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
        $string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
    }
    return $string;
}

/**
 * @desc 创建短信验证码
 * @param string $key 缓存key
 * @param int $length 短信码长度
 * @param int $expire 默认缓存时间
 * @return string
 */
function create_msg_code($key, $length = 6, $expire = 300) {
    $chars = '0123456789';
    $chars = str_shuffle($chars);
    $code = substr($chars, 0, $length);

    //生产环境发送正式验证码
    if (Env::get('app.environment') == 'production') {
        Cache::set('create_msg_code_' . $key, $code, $expire);
    } else {
        $code = '123456';
        Cache::set('create_msg_code_' . $key, $code, $expire);
    }
    //Log::write('验证码：'.$code,'info', true);
    return $code;
}

/**
 * @desc 验证短信验证码
 * @param string $key 缓存key
 * @param string $code 默认缓存时间
 * @return string
 */
function check_msg_code($key, $code) {
    $cacheCode = Cache::get('create_msg_code_' . $key);
    //Log::write('CacheCode：'.$cacheCode,'info', true);
    if (strcmp($code, $cacheCode) != 0) {
        return false;
    } else {
        return true;
    }
}

/**
 * 生成待签名字符串
 * 对数组里的每一个值从a到z的顺序排序，若遇到相同首字母，则看第二个字母以此类推。
 * 排序完成后，再把所有数组值以‘&’字符连接起来
 * @param  array $params 待签名参数
 * @return string
 */
function build_link_string($params) {
    ksort($params);

    $data = [];
    foreach ($params as $k => $v) {
        if ($v == '' || $v === null) {
            continue;
        }
        array_push($data, $k . '=' . $v);
    }
    return implode('&', $data);
}

/**
 * @创建签名
 * @param array $data
 * @param string $signKey
 * @return string
 */
function build_sign($data, $signKey) {
    unset($data['sign']);
    ksort($data);

    $param = [];
    foreach ($data as $k => $v) {
        if ($v == '' || $v === null) {
            continue;
        }
        array_push($param, $k . '=' . $v);
    }
    $queryString = implode('&', $param);

    if (get_magic_quotes_gpc()) {
        $queryString = stripslashes($queryString);
    }
    return md5($queryString . $signKey);
}

/**
 * @desc 验证签名
 * @param array $data
 * @param string $signKey 商户key
 * 生成待签名字符串
 * 对数组里的每一个值从a到z的顺序排序，若遇到相同首字母，则看第二个字母以此类推。
 * 排序完成后，再把所有数组值以‘&’字符连接起来
 * @return bool
 */
function check_sign($data, $signKey) {
    writeLog('post参数为：', 'check_sign');
    writeLog($data, 'check_sign');

    $clientSign = $data['sign'];
    unset($data['sign']);
    ksort($data);

    $param = [];
    foreach ($data as $k => $v) {
        if ($v == '' || $v === null) {
            continue;
        }
        array_push($param, $k . '=' . $v);
    }
    $queryString = implode('&', $param);

    //如果存在转义字符，那么去掉转义
    if (get_magic_quotes_gpc()) {
        $queryString = stripslashes($queryString);
    }

    //writeLog('queryString:'.$queryString, 'check_sign');

    $sign = md5($queryString . $signKey);

    writeLog('正确的签名为：'.$sign, 'check_sign');

    return $clientSign == strtolower($sign);
}

/**
 * @desc 获取带参数的url
 * @param string $url
 * @param array $data
 * @return string
 */
function getParamsUrl($url, $data) {
    if (is_array($data)) {
        $param = [];
        foreach ($data as $k => $v) {
            if ($v == '' || $v === null) {
                continue;
            }
            array_push($param, $k . '=' . $v);
        }
        $queryString = implode('&', $param);
    } else {
        $queryString = $data;
    }
    /**
     * 解析原始地址
     * 完整链接：http://aa.abc.com/download/v3?agentCode=55421603&channelCode=android
     * array() {
     *    "scheme"=> "http"
     *    "host"  => "aa.abc.com"
     *    "path"  => "/download/v3"
     *    "query" => "agentCode=55421603&channelCode=android"
     * }
     */
    $parseInfo = parse_url($url);
    if (isset($parseInfo['query'])) {
        return $url . '&' . $queryString;
    } else {
        return $url . '?' . $queryString;
    }
}

/**
 * @desc 写日志
 * @param $data
 * @param string $fileName 文件名称
 * @param string $ip ip地址
 * @return array|string|null
 */
function writeLog($data, $fileName = 'default', $ip = '0.0.0.0') {
    $runtime = Env::get('runtime_path');

    //设置日志最大为10M
    $max_size = 1024 * 1024 * 10;

    $logPath = $runtime . 'log/' . date('Ym/d/');
    !is_dir($logPath) && mkdir($logPath, 0755, true);
    $logFilename = $logPath . $fileName . ".log";

    //若果文件存在且文件大于10M就重新分割生成 log_20200512001120.log
    if (file_exists($logFilename) && (abs(filesize($logFilename)) > $max_size)) {
        rename($logFilename, dirname($logFilename) . '/' . $fileName . date('_YmdHis') . ".log");
    }

    //如果是查询的sql，则默认返回对象。这里需要toArray转换为数组
    if ($data instanceof Collection || $data instanceof Model) {
        $data = $data->toArray();
    }

    if (is_array($data)) {
        $data = var_export($data, true);
    }

    $currentTime = '[' . date('Y-m-d H:i:s') . '][ip:' . $ip . ']';

    file_put_contents($logFilename, $currentTime . "\r\n" . $data . "\r\n", FILE_APPEND);
}


/**
 * 判断字符串是否为 Json 格式
 * 
 * @param  string  $data  Json 字符串
 * @param  bool    $assoc 是否返回关联数组。默认返回对象
 * 
 * @return array|bool|object 成功返回转换后的对象或数组，失败返回 false
 */
function is_json($data = '', $assoc = false) {
    $data = json_decode($data, $assoc);
    if (($data && is_object($data)) || (is_array($data) && !empty($data))) {
        return $data;
    }
    return false;
}

/**
 * @desc 将对象转化为数组
 * @param $array
 * @return array
 */
function object_array($array) {
    if(is_object($array)) {
        $array = (array)$array;
    }
    if(is_array($array)) {
        foreach($array as $key=>$value) {
            $array[$key] = object_array($value);
        }
    }
    return $array;
}

/**
 * AES加密
 * @param string $secretKey 安全加密key
 * @param string $text 明文
 * @return string
 */
function aesEncrypt($text, $secretKey){
    $aes = new CryptAES($secretKey);
    return $aes->encrypt($text);
}

/**
 * AES解密
 * @param string $secretKey 安全加密key
 * @param string $encryptText 解密密文
 * @return mixed
 */
function aesDecrypt($encryptText, $secretKey){
    $aes = new CryptAES($secretKey);
    return $aes->decrypt($encryptText);
}

/**
 * 将数值金额转换为中文大写金额
 * @param $amount float 金额(支持到分)
 * @param $type   int   补整类型,0:到角补整;1:到元补整
 * @return mixed 中文大写金额
 */
function convertAmountToCn($amount, $type = 1) {
    // 判断输出的金额是否为数字或数字字符串
    if(!is_numeric($amount)){
        return "要转换的金额只能为数字!";
    }

    // 金额为0,则直接输出"零元整"
    if($amount == 0) {
        return "人民币零元整";
    }

    // 金额不能为负数
    if($amount < 0) {
        return "要转换的金额不能为负数!";
    }

    // 金额不能超过万亿,即12位
    if(strlen($amount) > 12) {
        return "要转换的金额不能为万亿及更高金额!";
    }

    // 预定义中文转换的数组
    $digital = array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
    // 预定义单位转换的数组
    $position = array('仟', '佰', '拾', '亿', '仟', '佰', '拾', '万', '仟', '佰', '拾', '元');

    // 将金额的数值字符串拆分成数组
    $amountArr = explode('.', $amount);

    // 将整数位的数值字符串拆分成数组
    $integerArr = str_split($amountArr[0], 1);

    // 将整数部分替换成大写汉字
    //$result = '人民币';
    $result = '';
    $integerArrLength = count($integerArr);     // 整数位数组的长度
    $positionLength = count($position);         // 单位数组的长度
    for($i = 0; $i < $integerArrLength; $i++) {
        // 如果数值不为0,则正常转换
        if($integerArr[$i] != 0){
            $result = $result . $digital[$integerArr[$i]] . $position[$positionLength - $integerArrLength + $i];
        }else{
            // 如果数值为0, 且单位是亿,万,元这三个的时候,则直接显示单位
            if(($positionLength - $integerArrLength + $i + 1)%4 == 0){
                $result = $result . $position[$positionLength - $integerArrLength + $i];
            }
        }
    }

    // 如果小数位也要转换
    if($type == 0) {
        // 将小数位的数值字符串拆分成数组
        $decimalArr = str_split($amountArr[1], 1);
        // 将角替换成大写汉字. 如果为0,则不替换
        if($decimalArr[0] != 0){
            $result = $result . $digital[$decimalArr[0]] . '角';
        }
        // 将分替换成大写汉字. 如果为0,则不替换
        if($decimalArr[1] != 0){
            $result = $result . $digital[$decimalArr[1]] . '分';
        }
    }else{
        $result = $result . '整';
    }
    return $result;
}

/**
 * 格式化银行卡号为四位空格分隔
 * @param $card_no
 * @return string
 */
function formatCardNo($card_no){
    if(stripos($card_no, '@') > 0 || strlen($card_no) == 11){
        return $card_no;
    }
    $length = strlen($card_no);
    $stage = ceil($length / 4);
    $state_arr = [];
    for ($i = 0; $i < $stage; $i++){
        $state_arr[] = substr($card_no, $i * 4, 4);
    }
    return implode(' ', $state_arr);
}

/**
 * 上传文件
 * @param $name
 * @return string
 * @throws Exception
 */
function fileUpload($name){
    if(!$_FILES[$name] || $_FILES[$name]["size"] <= 0){
        return false;
    }
    if ($_FILES[$name]["size"] < 81960000)
    {
        if ($_FILES[$name]["error"] > 0)
        {
            return false;
        }
        else
        {
            ini_set("display_errors", "On");error_reporting(E_ALL | E_STRICT);
            // 读取ext
            $names = explode('.', $_FILES[$name]["name"]);
            $ext = array_pop($names);
            $basename = md5(uniqid('daifu_', true));
            $file_name = basename($basename.'.'.$ext);
            $s = move_uploaded_file($_FILES[$name]["tmp_name"], 'upload/'.$file_name);
            return '/upload/'.$file_name;
        }
    }
    else
    {
        return false;
    }
}


// 重定向并带post数据
function build_form($url,$post_data,$method = 'post'){
    $input_param = '';
    foreach($post_data as $k => $v){
        $input_param .= "<input type='hidden' name='{$k}' value='{$v}' />";
    }
    /**
     * <meta charset="utf-8" />
    <meta http-equiv="content-type" name="keywords" content="" />
    <meta http-equiv="content-type" name="description" content="" />
    <meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
     */
    $html = <<<EOT
<form method="$method" action="$url" id="submit">
$input_param
<input type="submit" value="立即提交" style="opacity:0" />
</form>
<script>document.getElementById('submit').submit();</script>
EOT;
    $html = str_replace("\r\n",'',$html);
    $html = str_replace(PHP_EOL,'',$html);
    return $html;
}